﻿using PGMHelper;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace HystereticBasic
{
    /// <summary>
    /// 对外方法
    /// </summary>
    public static class ExternalMethod
    {
        /// <summary>
        /// 滞回曲线对比
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="defromFactor"></param>
        /// <param name="forceFactor"></param>
        /// <param name="filePath"></param>
        public static void ForceDispVSToChartGridview(ForceDispObj exObj, ForceDispObj simObj, 
            Chart chart, Chart skeletonChart, DataGridView view, DataGridView eview, 
            SkeletonSoftenMethod sMethod = SkeletonSoftenMethod.ModEnvelope, 
            bool isExFilter = false,int sPtSparaCount = -1, int skeletonSpara = -1)
        {
            //清空序列
            chart.Series.Clear();
            skeletonChart.Series.Clear();
            //相对误差
            var errorData = new GridViewDatas();
            var mainData = new GridViewDatas();

            //列表储存数据
            var eValueList = new List<double>();
            var sValueList = new List<double>();
            var errorValueList = new List<double>();

            //函数指针 记录骨架信息
            Action<MontForceDispObj, bool, string, Color, List<double>> addSkeleton = (obj, isPos, name, color, vList) =>
            {
                //目标名称
                var tName = name + (isPos ? "+" : "-");
                //绘制骨架
                obj.ToChart(skeletonChart, tName, color, 2);
                //添加数据
                mainData.AddRange(obj.GetData(tName));
                //负向骨架
                if (!isPos)
                {
                    obj.DispAmplitude(-1); obj.ForceAmplitude(-1);
                }
                //构造延性
                var duc = new DuctilityObj(obj, tName, 0.8F, 0.7F);
                //添加峰值承载力
                vList.Add(duc[DataType.DuctilityPeakForce, DuctilityMethod.Park]);
                vList.Add(duc[DataType.DuctilityYieldDisp, DuctilityMethod.Park]);
                vList.Add(duc[DataType.DuctilityUltimateDisp, DuctilityMethod.Park]);
                vList.Add(duc[DataType.DuctilityFactor, DuctilityMethod.Park]);
            };

            //获得骨架
            var exSOE = new BasicData(exObj.ToList(), sMethod);
            //试验滞回曲线过滤
            if (isExFilter)
            {
                exObj = exSOE.GetFilterForceDispObj();
                exSOE = new BasicData(exObj.ToList(), sMethod);
            }
            //构件试验
            exObj.ToChart(chart, "试验", Color.Red, 1, false);
            mainData.AddRange(exObj.GetData("试验"));
            //骨架曲线
            var epSkeleton = exSOE.GetSkeletonObj(true);
            var enSkeleton = exSOE.GetSkeletonObj(false);
            //骨架是否离散
            if(skeletonSpara > 0 )
            {
                epSkeleton = epSkeleton.GetForceDispObjBySameIncreate(skeletonSpara);
                enSkeleton = enSkeleton.GetForceDispObjBySameIncreate(skeletonSpara);
            }
            //添加数据
            eValueList.Add(exSOE[DataType.AccumulateEnergy].Last());
            addSkeleton(epSkeleton, true, "试验骨架", Color.Red, eValueList);
            addSkeleton(enSkeleton, false, "试验骨架", Color.Red, eValueList);
            //添加数据
            errorData.Add(new GridViewColumn(eValueList, 4, "试验"));

            //绘制
            if (simObj.Count != 0)
            {
                //获得骨架
                var sSOE = new BasicData(simObj.ToList(), sMethod);
                //重构数据
                if (sPtSparaCount > 0) 
                    simObj = sSOE.GetForceDispObjBySameIncreate(sPtSparaCount);
                //数据
                simObj.ToChart(chart, "模拟", Color.Blue, 2);
                mainData.AddRange(simObj.GetData("模拟"));
                //获得骨架
                var spSkeleton = sSOE.GetSkeletonObj(true);
                var snSkeleton = sSOE.GetSkeletonObj(false);
                //骨架是否离散
                if (skeletonSpara > 0)
                {
                    spSkeleton = spSkeleton.GetForceDispObjBySameIncreate(skeletonSpara);
                    snSkeleton = snSkeleton.GetForceDispObjBySameIncreate(skeletonSpara);
                }
                //添加数据
                sValueList.Add(sSOE[DataType.AccumulateEnergy].Last());
                addSkeleton(spSkeleton, true, "模拟骨架", Color.Blue, sValueList);
                addSkeleton(snSkeleton, false, "模拟骨架", Color.Blue, sValueList);
                //添加数据
                errorData.Add(new GridViewColumn(sValueList, 4, "模拟"));
                //计算相对误差
                for (int i = 0; i < eValueList.Count; i++)
                    errorValueList.Add((sValueList[i] - eValueList[i]) / eValueList[i]);
                //添加数据
                errorData.Add(new GridViewColumn(errorValueList, 4, "相对误差"));
            }
            //添加数据
            view.AddDatas(mainData);
            eview.AddDatas(errorData);
        }


    }
}
